<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>防抖和节流</title>
</head>
<body>
<div id="content" style="height:150px;line-height:150px;text-align:center; color: #fff;background-color:#ccc;font-size:80px;"></div>
<script>
    let num = 1;
    let content = document.getElementById('content');

    function count() {
        content.innerHTML = num++;
    };
    // 防抖
    // content.onmousemove = count;
    // 延时执行版，在触发事件后1秒内又触发了，又会重新计算时间，直到不触发了为止
    // function debounce(func, wait) {
    //     let timeout;
    //     return function () {
    //         let context = this;
    //         let args = arguments;
    //
    //         if (timeout) clearTimeout(timeout);
    //
    //         timeout = setTimeout(() => {
    //             func.apply(context, args)
    //         }, wait);
    //     }
    // }
    // 立即执行版，触发函数立即执行，只有n秒内不触发了才能执行完毕
    function debounce(func,wait) {
        let timeout;
        return function () {
            let context = this;
            let args = arguments;

            if (timeout) clearTimeout(timeout);

            let callNow = !timeout;
            timeout = setTimeout(() => {
                timeout = null;
            }, wait)

            if (callNow) func.apply(context, args)
        }
    }
    /**
     * @desc 函数防抖
     * @param func 函数
     * @param wait 延迟执行毫秒数
     * @param immediate true 表立即执行，false 表非立即执行
     */
    function debounce(func,wait,immediate) {
        let timeout;

        return function () {
            let context = this;
            let args = arguments;

            if (timeout) clearTimeout(timeout);
            if (immediate) {
                var callNow = !timeout;
                timeout = setTimeout(() => {
                    timeout = null;
                }, wait)
                if (callNow) func.apply(context, args)
            }
            else {
                timeout = setTimeout(function(){
                    func.apply(context, args)
                }, wait);
            }
        }
    }
    content.onmousemove = debounce(count,1000);
    /**
     * @desc 函数节流
     * @param func 函数
     * @param wait 延迟执行毫秒数
     * @param type 1 表时间戳版，2 表定时器版
     */
    function throttle(func, wait ,type) {
        if(type===1){
            let previous = 0;
        }else if(type===2){
            let timeout;
        }
        return function() {
            let context = this;
            let args = arguments;
            if(type===1){
                let now = Date.now();

                if (now - previous > wait) {
                    func.apply(context, args);
                    previous = now;
                }
            }else if(type===2){
                if (!timeout) {
                    timeout = setTimeout(() => {
                        timeout = null;
                        func.apply(context, args)
                    }, wait)
                }
            }
        }
    }
</script>
</body>
</html>
